package cn.skyquant.quant4j.api.account;

import cn.skyquant.quant4j.api.dto.ResultDTO;
import cn.skyquant.quant4j.api.enums.BorkerType;
import cn.skyquant.quant4j.api.service.BaseServiceProxy;
import cn.skyquant.quant4j.sdk.enums.Status;
import com.alibaba.fastjson.JSONObject;

import java.util.HashMap;
import java.util.Map;

/**
 * 使用HTTP的代理
 */
public class AccountServiceProxy extends BaseServiceProxy implements AccountService {
    private static final String url = "/account";

    public AccountServiceProxy(String accountCode, BorkerType borkerType) {
        super(accountCode, borkerType);
    }

    @Override
    public ResultDTO<AccountDTO> reg(String accountCode, BorkerType borkerType, String accountName, String borkerName, String currency, String accountType, String parentCode) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("code", accountCode);
        paramMap.put("borker_type", borkerType.name());
        paramMap.put("name", accountName);
        paramMap.put("borker_name", borkerName);
        paramMap.put("currency", currency);
        paramMap.put("account_type", accountType);
        paramMap.put("parent_code", parentCode);
        JSONObject jsonObject = post(url, paramMap);
        if (jsonObject != null) {
            boolean ok = jsonObject.getBoolean("ok");
            if (!ok) {
                String message = jsonObject.getString("message");
                return ResultDTO.error(message);
            } else {
                JSONObject data = jsonObject.getJSONObject("data");
                if (data != null) {
                    try {
                        AccountDTO accountDTO = getAccountDTOFromJsonObject(data);
                        return ResultDTO.success(accountDTO);
                    } catch (Exception e) {
                        return error;
                    }
                }
            }
        }
        return error;
    }

    @Override
    public ResultDTO<Void> update(String code,BorkerType borkerType, double balance, double equity, double usedMargin, long borkerTime) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("code", code);
        paramMap.put("borkerType", borkerType.name());
        paramMap.put("balance", String.valueOf(balance));
        paramMap.put("equity", String.valueOf(equity));
        paramMap.put("used_margin", String.valueOf(usedMargin));
        paramMap.put("borker_time", String.valueOf(borkerTime));
        JSONObject jsonObject = put(url, paramMap);
        if (jsonObject != null) {
            boolean ok = jsonObject.getBoolean("ok");
            String message = jsonObject.getString("message");
            if (ok) {
                return ResultDTO.success;
            } else {
                return ResultDTO.error(message);
            }
        }
        return error;
    }

    @Override
    public ResultDTO<Void> notice(int accountId) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("accountId", String.valueOf(accountId));
        JSONObject jsonObject = get(url, paramMap);
        if (jsonObject != null) {
            boolean ok = jsonObject.getBoolean("ok");
            String message = jsonObject.getString("message");
            if (ok) {
                return ResultDTO.success;
            } else {
                return ResultDTO.error(message);
            }
        }
        return error;
    }

    @Override
    public ResultDTO<AccountDTO> get(String accountCode, BorkerType borkerType) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("code", accountCode);
        paramMap.put("borker_type", borkerType.name());
        JSONObject jsonObject = get(url,paramMap);
        if (jsonObject != null) {
            boolean ok = jsonObject.getBoolean("ok");
            if (!ok) {
                String message = jsonObject.getString("message");
                return ResultDTO.error(message);
            } else {
                JSONObject data = jsonObject.getJSONObject("data");
                if (data != null) {
                    try {
                        AccountDTO accountDTO = getAccountDTOFromJsonObject(data);
                        return ResultDTO.success(accountDTO);
                    } catch (Exception e) {
                        return error;
                    }
                }
            }
        }
        return error;
    }

    @Override
    public ResultDTO<AccountDTO> create(String accountCode, BorkerType borkerType, String accountType, String accountName, String borkerName, String currency, String parentCode) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("code", accountCode);
        paramMap.put("borker_type", borkerType.name());
        paramMap.put("name", accountName);
        paramMap.put("borker_name", borkerName);
        paramMap.put("currency", currency);
        paramMap.put("account_type", accountType);
        paramMap.put("parent_code", parentCode);
        JSONObject jsonObject = post(url, paramMap);
        if (jsonObject != null) {
            boolean ok = jsonObject.getBoolean("ok");
            if (!ok) {
                String message = jsonObject.getString("message");
                return ResultDTO.error(message);
            } else {
                JSONObject data = jsonObject.getJSONObject("data");
                if (data != null) {
                    try {
                        AccountDTO accountDTO = getAccountDTOFromJsonObject(data);
                        return ResultDTO.success(accountDTO);
                    } catch (Exception e) {
                        return error;
                    }
                }
            }
        }
        return error;
    }

    @Override
    public ResultDTO<Void> updateType(int accountId, String type) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("type", type);
        JSONObject jsonObject = post(url+"/"+accountId+"/updateType", paramMap);
        if (jsonObject != null) {
            boolean ok = jsonObject.getBoolean("ok");
            String message = jsonObject.getString("message");
            if (ok) {
                return ResultDTO.success;
            } else {
                return ResultDTO.error(message);
            }
        }
        return error;
    }

    private AccountDTO getAccountDTOFromJsonObject(JSONObject data) {
        String r_parentCode = data.getString("parentCode");
        String r_name = data.getString("name");
        String r_code = data.getString("code");
        String r_borkerType = data.getString("borkerType");
        String r_borkerName = data.getString("borkerName");
        String r_currency = data.getString("currency");
        String r_type = data.getString("type");
        Integer r_id = data.getInteger("id");
        String status = data.getString("status");
        double r_balance = data.getDouble("balance");
        double r_equity = data.getDouble("equity");
        double r_usedMargin = data.getDouble("usedMargin");
        AccountDTO accountDTO = new AccountDTO();
        accountDTO.parentCode = r_parentCode;
        accountDTO.id = r_id;
        accountDTO.name = r_name;
        accountDTO.code = r_code;
        accountDTO.borkerType = BorkerType.valueOf(r_borkerType);
        accountDTO.borkerName = r_borkerName;
        accountDTO.currency = r_currency;
        accountDTO.type = r_type;
        accountDTO.balance = r_balance;
        accountDTO.equity = r_equity;
        accountDTO.usedMargin = r_usedMargin;
        accountDTO.status = Status.valueOf(status);
        return accountDTO;
    }
}